home *** CD-ROM | disk | FTP | other *** search
/ Practical Algorithms for Image Analysis / Practical Algorithms for Image Analysis.iso / TARFILE.GZ / tarfile / libtiff / tools / sgisv.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-09-11  |  8.3 KB  |  310 lines

  1. /* $Header: /usr/people/sam/tiff/tools/RCS/sgisv.c,v 1.25 1996/01/10 19:35:33 sam Rel $ */
  2.  
  3. /*
  4.  * Copyright (c) 1990-1996 Sam Leffler
  5.  * Copyright (c) 1991-1996 Silicon Graphics, Inc.
  6.  *
  7.  * Permission to use, copy, modify, distribute, and sell this software and 
  8.  * its documentation for any purpose is hereby granted without fee, provided
  9.  * that (i) the above copyright notices and this permission notice appear in
  10.  * all copies of the software and related documentation, and (ii) the names of
  11.  * Sam Leffler and Silicon Graphics may not be used in any advertising or
  12.  * publicity relating to the software without the specific, prior written
  13.  * permission of Sam Leffler and Silicon Graphics.
  14.  * 
  15.  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
  16.  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
  17.  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
  18.  * 
  19.  * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
  20.  * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
  21.  * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  22.  * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
  23.  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
  24.  * OF THIS SOFTWARE.
  25.  */
  26.  
  27. #include <stdio.h>
  28. #include <stdlib.h>
  29. #include <string.h>
  30.  
  31. #include <gl.h>
  32. #include <ctype.h>
  33.  
  34. #include "tiffio.h"
  35.  
  36. typedef unsigned char u_char;
  37. typedef unsigned long u_long;
  38.  
  39. #define    streq(a,b)    (strcmp(a,b) == 0)
  40. #define    strneq(a,b,n)    (strncmp(a,b,n) == 0)
  41.  
  42. uint32    rowsperstrip = (uint32) -1;
  43. uint16    compression = COMPRESSION_LZW;
  44. uint16    config = PLANARCONFIG_CONTIG;
  45. uint16    predictor = 0;
  46. int    xmaxscreen;
  47. int    ymaxscreen;
  48. uint16    photometric = PHOTOMETRIC_RGB;
  49. int    jpegcolormode = JPEGCOLORMODE_RGB;
  50. int    quality = 75;        /* JPEG quality */
  51.  
  52. static    void usage(void);
  53. static    void tiffsv(char*, int, int, int, int);
  54.  
  55. int
  56. main(int argc, char* argv[])
  57. {
  58.     int c;
  59.     extern int optind;
  60.     extern char* optarg;
  61.  
  62.     while ((c = getopt(argc, argv, "c:p:r:")) != -1)
  63.         switch (c) {
  64.         case 'b':        /* save as b&w */
  65.             photometric = PHOTOMETRIC_MINISBLACK;
  66.             break;
  67.         case 'c':        /* compression scheme */
  68.             if (streq(optarg, "none"))
  69.                 compression = COMPRESSION_NONE;
  70.             else if (streq(optarg, "packbits"))
  71.                 compression = COMPRESSION_PACKBITS;
  72.             else if (strneq(optarg, "jpeg", 4)) {
  73.                 char* cp = strchr(optarg, ':');
  74.                 if (cp && isdigit(cp[1]))
  75.                     quality = atoi(cp+1);
  76.                 if (cp && strchr(cp, 'r'))
  77.                     jpegcolormode = JPEGCOLORMODE_RAW;
  78.                 compression = COMPRESSION_JPEG;
  79.             } else if (strneq(optarg, "lzw", 3)) {
  80.                 char* cp = strchr(optarg, ':');
  81.                 if (cp)
  82.                     predictor = atoi(cp+1);
  83.                 compression = COMPRESSION_LZW;
  84.             } else
  85.                 usage();
  86.             break;
  87.         case 'p':        /* planar configuration */
  88.             if (streq(optarg, "separate"))
  89.                 config = PLANARCONFIG_SEPARATE;
  90.             else if (streq(optarg, "contig"))
  91.                 config = PLANARCONFIG_CONTIG;
  92.             else
  93.                 usage();
  94.             break;
  95.         case 'r':        /* rows/strip */
  96.             rowsperstrip = atoi(optarg);
  97.             break;
  98.         case '?':
  99.             usage();
  100.             /*NOTREACHED*/
  101.         }
  102.     if (argc - optind != 1 && argc - optind != 5)
  103.         usage();
  104.     xmaxscreen = getgdesc(GD_XPMAX)-1;
  105.     ymaxscreen = getgdesc(GD_YPMAX)-1;
  106.     foreground();
  107.     noport();
  108.     winopen("tiffsv");
  109.     if (argc - optind == 5)
  110.         tiffsv(argv[optind],
  111.             atoi(argv[optind+1]), atoi(argv[optind+2]),
  112.             atoi(argv[optind+3]), atoi(argv[optind+4]));
  113.     else
  114.         tiffsv(argv[optind], 0, xmaxscreen, 0, ymaxscreen);
  115.     return (0);
  116. }
  117.  
  118. char* stuff[] = {
  119. "usage: tiffsv [options] outimage.tif [x1 x2 y1 y2] [-b]",
  120. "where options are:",
  121. " -p contig    pack samples contiguously (e.g. RGBRGB...)",
  122. " -p separate    store samples separately (e.g. RRR...GGG...BBB...)",
  123. "",
  124. " -r #        make each strip have no more than # rows",
  125. "",
  126. " -c lzw[:opts]    compress output with Lempel-Ziv & Welch encoding",
  127. " -c jpeg[:opts]compress output with JPEG encoding",
  128. " -c packbits    compress output with packbits encoding",
  129. " -c none    use no compression algorithm on output",
  130. "",
  131. "JPEG options:",
  132. " #        set compression quality level (0-100, default 75)",
  133. " r        output color image as RGB rather than YCbCr",
  134. "",
  135. "LZW options:",
  136. " #        set predictor value for Lempel-Ziv & Welch encoding",
  137. "For example, -c lzw:2 to get LZW-encoded data with horizontal differencing",
  138. NULL
  139. };
  140.  
  141. static void
  142. usage(void)
  143. {
  144.     char buf[BUFSIZ];
  145.     int i;
  146.  
  147.     setbuf(stderr, buf);
  148.     for (i = 0; stuff[i] != NULL; i++)
  149.         fprintf(stderr, "%s\n", stuff[i]);
  150.     exit(-1);
  151. }
  152.  
  153. static void
  154. svRGBSeparate(TIFF* tif, u_long* ss, int xsize, int ysize)
  155. {
  156.     tsize_t stripsize = TIFFStripSize(tif);
  157.     u_char *rbuf = (u_char *)_TIFFmalloc(3*stripsize);
  158.     u_char *gbuf = rbuf + stripsize;
  159.     u_char *bbuf = gbuf + stripsize;
  160.     register int y;
  161.  
  162.     for (y = 0; y <= ysize; y += rowsperstrip) {
  163.         u_char *rp, *gp, *bp;
  164.         register int x;
  165.         register uint32 n;
  166.  
  167.         n = rowsperstrip;
  168.         if (n > ysize-y+1)
  169.             n = ysize-y+1;
  170.         rp = rbuf; gp = gbuf; bp = bbuf;
  171.         do {
  172.             for (x = 0; x <= xsize; x++) {
  173.                 u_long v = ss[x];
  174.                 rp[x] = v;
  175.                 gp[x] = v >> 8;
  176.                 bp[x] = v >> 16;
  177.             }
  178.             rp += xsize+1, gp += xsize+1, bp += xsize+1;
  179.             ss += xsize+1;
  180.         } while (--n);
  181.         if (TIFFWriteEncodedStrip(tif, TIFFComputeStrip(tif,y,0),
  182.             rbuf, stripsize) < 0)
  183.             break;
  184.         if (TIFFWriteEncodedStrip(tif, TIFFComputeStrip(tif,y,1),
  185.             gbuf, stripsize) < 0)
  186.             break;
  187.         if (TIFFWriteEncodedStrip(tif, TIFFComputeStrip(tif,y,2),
  188.             bbuf, stripsize) < 0)
  189.             break;
  190.     }
  191.     _TIFFfree(rbuf);
  192. }
  193.  
  194. static void
  195. svRGBContig(TIFF* tif, u_long* ss, int xsize, int ysize)
  196. {
  197.     register int x, y;
  198.     tsize_t stripsize = TIFFStripSize(tif);
  199.     u_char *strip = (u_char *)_TIFFmalloc(stripsize);
  200.  
  201.     for (y = 0; y <= ysize; y += rowsperstrip) {
  202.         register u_char *pp = strip;
  203.         register uint32 n;
  204.  
  205.         n = rowsperstrip;
  206.         if (n > ysize-y+1)
  207.             n = ysize-y+1;
  208.         do {
  209.             for (x = 0; x <= xsize; x++) {
  210.                 u_long v = ss[x];
  211.                 pp[0] = v;
  212.                 pp[1] = v >> 8;
  213.                 pp[2] = v >> 16;
  214.                 pp += 3;
  215.             }
  216.             ss += xsize+1;
  217.         } while (--n);
  218.         if (TIFFWriteEncodedStrip(tif, TIFFComputeStrip(tif,y,0),
  219.             strip, stripsize) < 0)
  220.             break;
  221.     }
  222.     _TIFFfree(strip);
  223. }
  224.  
  225. #undef RED
  226. #undef GREEN
  227. #undef BLUE
  228. #define    CVT(x)    (((x)*255)/100)
  229. #define    RED    CVT(28)        /* 28% */
  230. #define    GREEN    CVT(59)        /* 59% */
  231. #define    BLUE    CVT(11)        /* 11% */
  232.  
  233. static void
  234. svGrey(TIFF* tif, u_long* ss, int xsize, int ysize)
  235. {
  236.     register int x, y;
  237.     u_char *buf = (u_char *)_TIFFmalloc(TIFFScanlineSize(tif));
  238.  
  239.     for (y = 0; y <= ysize; y++) {
  240.         for (x = 0; x <= xsize; x++) {
  241.             u_char *cp = (u_char *)&ss[x];
  242.             buf[x] = (RED*cp[3] + GREEN*cp[2] + BLUE*cp[1]) >> 8;
  243.         }
  244.         if (TIFFWriteScanline(tif, buf, (uint32) y, 0) < 0)
  245.             break;
  246.         ss += xsize+1;
  247.     }
  248.     _TIFFfree(buf);
  249. }
  250.  
  251. #define    MIN(a,b)    ((a)<(b)?(a):(b))
  252. #define    ABS(x)        ((x)<0?-(x):(x))
  253.  
  254. static void
  255. tiffsv(char* name, int x1, int x2, int y1, int y2)
  256. {
  257.     TIFF *tif;
  258.     int xsize, ysize;
  259.     int xorg, yorg;
  260.     u_long *scrbuf;
  261.  
  262.     xorg = MIN(x1,x2);
  263.     yorg = MIN(y1,y2);
  264.     if (xorg<0)
  265.         xorg = 0;
  266.     if (yorg<0)
  267.         yorg = 0;
  268.     xsize = ABS(x2-x1);
  269.     ysize = ABS(y2-y1);
  270.     if (xorg+xsize > xmaxscreen)
  271.         xsize = xmaxscreen-xorg;
  272.     if (yorg+ysize > ymaxscreen)
  273.         ysize = ymaxscreen-yorg;
  274.     tif = TIFFOpen(name, "w");
  275.     TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, (uint32) (xsize+1));
  276.     TIFFSetField(tif, TIFFTAG_IMAGELENGTH, (uint32) (ysize+1));
  277.     TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 8);
  278.     TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL,
  279.         photometric == PHOTOMETRIC_RGB ? 3 : 1);
  280.     TIFFSetField(tif, TIFFTAG_PLANARCONFIG, config);
  281.     TIFFSetField(tif, TIFFTAG_COMPRESSION, compression);
  282.     switch (compression) {
  283.     case COMPRESSION_JPEG:
  284.         if (photometric == PHOTOMETRIC_RGB && jpegcolormode == JPEGCOLORMODE_RGB)
  285.             photometric = PHOTOMETRIC_YCBCR;
  286.         TIFFSetField(tif, TIFFTAG_JPEGQUALITY, quality);
  287.         TIFFSetField(tif, TIFFTAG_JPEGCOLORMODE, jpegcolormode);
  288.         break;
  289.     case COMPRESSION_LZW:
  290.         if (predictor != 0)
  291.             TIFFSetField(tif, TIFFTAG_PREDICTOR, predictor);
  292.         break;
  293.     }
  294.     TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, photometric);
  295.     TIFFSetField(tif, TIFFTAG_ORIENTATION, ORIENTATION_BOTLEFT);
  296.     rowsperstrip = TIFFDefaultStripSize(tif, rowsperstrip);
  297.     TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, rowsperstrip);
  298.     scrbuf = (u_long *)_TIFFmalloc((xsize+1)*(ysize+1)*sizeof (u_long));
  299.     readdisplay(xorg, yorg, xorg+xsize, yorg+ysize, scrbuf, RD_FREEZE);
  300.     if (photometric == PHOTOMETRIC_RGB) {
  301.         if (config == PLANARCONFIG_SEPARATE)
  302.             svRGBSeparate(tif, scrbuf, xsize, ysize);
  303.         else
  304.             svRGBContig(tif, scrbuf, xsize, ysize);
  305.     } else
  306.         svGrey(tif, scrbuf, xsize, ysize);
  307.     (void) TIFFClose(tif);
  308.     _TIFFfree((char *)scrbuf);
  309. }
  310.